/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.ufpb.projetoesa.dados;

import br.ufpb.projetoesa.exceptions.AtualizacaoDeTurmaException;
import br.ufpb.projetoesa.exceptions.TurmaInexistenteException;
import br.ufpb.projetoesa.exceptions.TurmaInvalidaException;
import br.ufpb.projetoesa.exceptions.TurmaVaziaException;
import br.ufpb.projetoesa.negocio.Turma;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Rennan
 */
public class TurmaDAOBin implements TurmaDAO{
    
    private ObjectInputStream in;
    private ObjectOutputStream out;
    private File file;
    private List<Turma> turmas;
    
    //SINGLETON
    private static TurmaDAOBin turmaDaoBin;
    
    public static TurmaDAOBin getInstance(){
        if (turmaDaoBin == null)
            return new TurmaDAOBin();
        return turmaDaoBin;
    } 
    
    //CONSTRUTOR
    private TurmaDAOBin (){
        this.file = new File("Turmas.bin");
        this.turmas = new ArrayList<Turma>();
    }
    
    public void salvaTurmas() {        
        try {
            out = new ObjectOutputStream(new FileOutputStream(this.file));
            out.writeObject(this.turmas);
            out.flush();
            out.close();
        } catch (IOException ex){ 
            ex.printStackTrace(); 
        }
    }
    
    public void recuperaTurmas(){
        
        try{
            in = new ObjectInputStream(new FileInputStream(this.file));
            turmas = (List<Turma>) in.readObject();
            in.close();       
        } 
        catch (IOException ex){
            ex.printStackTrace();
        } 
        catch (ClassNotFoundException ex) {
            ex.printStackTrace(); 
        }       
    }
    
    public void criarArquivo () {
        try {
            File file = new File("Turmas.bin");
            if (!file.exists()) 
                file.createNewFile();
            
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
    
    public void removerArquivo() {
        File file = new File("Turmas.bin");
        if(file.exists()){
            file.delete();
            this.turmas.clear();
            return;
        }
    }
    
    @Override
    public List getTurmas() {
        return this.turmas;
    }
    
    /**
     * Este método Cria um stream para o arquivo, escreve a turma na lista, e grava a lista de turmas.
     * @param turma 
     */
    @Override
    public void insert(Turma turma) throws TurmaInvalidaException{
        if(turmas!=null){
            if(!turmas.contains(turma)){
                turmas.add(turma);
            }else{
                throw new TurmaInvalidaException("Existe uma turma com este mesmo ID " +
                                            turma.getID()+ " já salva.");
            }
        }         
    }
    
    

    /**
     * Este método verifica se a turma existe, se a lista de turmas não está vazia, e remove a
     * turma. Abre um stream e grava a lista de turmas sem a turma em questão.
     * @param turma 
     */
    
    public void delete(Turma turma) throws TurmaInexistenteException, TurmaVaziaException{
        turmas.remove(turma);         
    }

    /**
     * Este método Atualiza uma turma passada, removendo a antiga da lista encontrada pelo ID,
     * e colocando a nova passada como parametro.
     * @param turma
     * @throws AtualizacaoDeTurmaException 
     */
    @Override
    public void update(Turma turma) throws AtualizacaoDeTurmaException{
        for(Turma t : turmas){
            if (t.getID().equals(turma.getID())){
                turmas.remove(t);
                turmas.add(turma);
                this.salvaTurmas();
            }else{
                throw new AtualizacaoDeTurmaException("Não foi possível atualizar a turma.");
            }
        }
    }

    /**
     * Busca uma turma baseado no ID
     * @param id
     * @return Turma encontrada
     * @throws TurmaInexistenteException 
     */
    @Override
    public Turma findID(String id) throws TurmaInexistenteException {
        for (Turma t : turmas){
            if(t.getID().equals(id)){
                return t;
            } else {
                throw new TurmaInexistenteException("Não existe uma turma com este ID;");
            }    
        } 
        return null;
    }

    /**
     * Calcula o tamanho da lista no arquivo.
     * @return Tamanho da lista
     */
    @Override
    public int size() {
        return this.turmas.size();
    }    
}
